#ifndef NMEA0183_HPP
#define NMEA0183_HPP

#include "List.hpp"
#include "L2DataSet.hpp"

#define NMEA0183_PARSER_SENTENCE_LINE_BUFFER_SIZE 256

namespace NMEA0183 {

class SentenceParser {
public:
    explicit SentenceParser(DataSet *dataset);
    virtual bool parseArgs(int argc,char *argv[]) = 0;
    virtual const char *getFormatterID(void);
    virtual int getErrorNumber(void);
protected:
    DataSet *dataset;
    const char *formatter_id;
    int error_number;
};
        

class Parser {
public:
    explicit Parser(DataSet *dataset);

    bool addSentenceParser(const char *formatter_id);
    bool addSentenceParser(SentenceParser *sentence_parser);
    bool removeSentenceParser(const char *formatter_id,bool del);
    bool removeSentenceParser(SentenceParser *sentence_parser,bool del);
    SentenceParser *getSentenceParser(const char *formatter_id);

    bool setChecksumEnableStatus(bool status);
    bool getChecksumEnableStatus(void);

    void parse(const char *message,unsigned int length);
    void feed(const char chr);

    int getErrorNumber(void);
protected:
    DataSet *dataset;
    List<SentenceParser*> sentence_parsers;
    bool checksum_enable_status = true;
    int error_number;
    char sentence_line_buffer[NMEA0183_PARSER_SENTENCE_LINE_BUFFER_SIZE];
    int sentence_line_buffer_size = 0;
};

class SentenceGenerator {
public:
    explicit SentenceGenerator(DataSet *dataset);
    virtual unsigned int generate(char *buffer,unsigned int max_length,bool checksum_status = true) = 0;
    virtual const char *getFormatterID(void);
    virtual bool setTalkerID(const char *talker_id);
    virtual int getErrorNumber();
protected:
    DataSet *dataset;
    const char *formatter_id;
    const char *talker_id;
    int error_number;
};

class Generator {
public:
    explicit Generator(DataSet *dataset);

    bool addSentenceGenerator(const char *formatter_id);
    bool addSentenceGenerator(SentenceGenerator *sentence_generator);
    bool removeSentenceGenerator(const char *formatter_id,bool del);
    bool removeSentenceGenerator(SentenceGenerator *sentence_generator,bool del);
    SentenceGenerator *getSentenceGenerator(const char *formatter_id);

    bool setChecksumStatus(bool status);
    bool getChecksumStatus(void);

    unsigned int generate(char *buffer,unsigned int max_length);

    int getErrorNumber(void);
protected:
    DataSet *dataset;
    List<SentenceGenerator*> sentence_generators;
    bool checksum_status = true;
    int error_number;
};

SentenceParser *createSentenceParser(const char *formatter_id,DataSet *dataset);
SentenceGenerator *createSentenceGenerator(const char *formatter_id,DataSet *dataset);

}

#endif